﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Athena.Runtime.Server.Implementations
{
    using Message;
    using Transport;
    using Transport.Implementations;
    public class ServiceHost : ISerivceHost
    {
        private readonly Func<EndPoint, Task<ITransportMessageListener>> _transportMessageListenerFactory;

        private readonly IServiceExecutor _serviceExecutor;
        private ITransportMessageListener _tansportMessageListenerLink;

        public ServiceHost(Func<EndPoint, Task<ITransportMessageListener>> transportMessageListenerFactory, IServiceExecutor serviceExecutor)
        {
            _transportMessageListenerFactory = transportMessageListenerFactory;
            _serviceExecutor = serviceExecutor;
            _tansportMessageListenerLink = new TransportMessageListener();
            _tansportMessageListenerLink.Received += MessageReceivedByLink;
        }

        public async Task StartAsync(EndPoint endPoint)
        {
            var tansportMessageListener = await _transportMessageListenerFactory(endPoint);
            tansportMessageListener.Received += async (sender, message) =>
            {
                await Task.Run(() =>
                {
                    _tansportMessageListenerLink.OnReceived(sender, message);
                });
            };
        }

        public void Dispose()
        {
            (_serviceExecutor as IDisposable)?.Dispose();
        }

        private async Task MessageReceivedByLink(ITransportMessageSender sender, RpcTransportMessage message)
        {
            await _serviceExecutor.ExecuteAsync(sender, message);
        }
    }
}
